﻿using System;
using System.Collections.Generic;
using System.Text;

namespace LFractalLib
{
    
    /// <summary>
    /// Collection acts same as a List<T>, the only difference is that we notify every time an item is added or removed from collection
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionWithNotification<T> : IList<T>
    {
        private List<T> _innerList = null;
        public delegate void OnItemAddHandler(T itemAdded);
        public delegate void OnItemBeingRemovedHandler(T itemBeingRemoved);

        public event OnItemAddHandler ItemAdded = null;
        public event OnItemBeingRemovedHandler ItemRemoving = null;


        internal List<T> InnerList
        {
            get { return _innerList; }
        }

        public CollectionWithNotification()
        {
            _innerList = new List<T>();
        }

        #region IList<T> Members

        public int IndexOf(T item)
        {
            return _innerList.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            _innerList.Insert(index, item);
            // Time to notify
            if (ItemAdded != null)
            {
                ItemAdded(item);
            }
        }

        public void RemoveAt(int index)
        {
            if (ItemRemoving != null)
            {
                ItemRemoving(_innerList[index]);
            }

            _innerList.RemoveAt(index);
        }

        public T this[int index]
        {
            get
            {
                return _innerList[index];
            }
            set
            {
                _innerList[index] = value;
            }
        }

        #endregion

        #region ICollection<T> Members

        public void Add(T item)
        {
            _innerList.Add(item);
            if (ItemAdded != null)
            {
                ItemAdded(item);
            }
        }

        public void Clear()
        {
            // Time to notify that all items are about to be removed
            if (ItemRemoving != null)
            {
                foreach (T item in _innerList)
                {
                    ItemRemoving(item);
                }
            }

            _innerList.Clear();
        }

        public bool Contains(T item)
        {
            return _innerList.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            _innerList.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _innerList.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            if (ItemRemoving != null)
            {
                ItemRemoving(item);
            }

            return _innerList.Remove(item);
        }

        #endregion

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return _innerList.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _innerList.GetEnumerator();
        }

        #endregion
    }
}
